home *** CD-ROM | disk | FTP | other *** search
- /*************************** bv-bool-ops.c *****************************
-
- Purpose: Implementation of boolean operations as bit vectors.
-
- Provenance: Written and tested by S. Wartik, April 1991.
-
- Notes: None.
-
- **/
-
- #include "bv.h"
-
- static boolean error_occurred; /* TRUE iff an error occurred on the */
- /* last call to a boolean operator. */
-
- /**************************************************************************
-
- Create(lower, upper, s)
-
- Returns: void
-
- Purpose: Create a set capable of containing values in the range
- [lower,upper].
-
- Plan: Set the values of "s" to the parameters.
-
- Notes: This routine must be called before any of the other
- routines (save error_occurred()) will work.
-
- **/
-
- void Create(lower, upper, s)
- int lower, upper; /* in: gives the set's domain. */
- set *s; /* out: the set. */
- {
- if ( lower > upper || (upper - lower) >= MAX_ELEMENTS ) {
- error_occurred = TRUE;
- return;
- }
- s->lower = lower;
- s->upper = upper;
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Clear(s)
-
- Returns: void
-
- Purpose: Indicate that set s is empty.
-
- Plan: Set all bits of s to 0.
-
- Notes: The Create() function does not automatically clear
- a set; this routine must be called to do so.
-
- **/
-
- void Clear(s)
- set *s; /* out: the set to be cleared. */
- {
- register int i, Number_Of_Bytes;
- Number_Of_Bytes = (s->upper - s->lower)/WORDSIZE + 1;
- for ( i = 0; i < Number_Of_Bytes; i++ )
- s->bits[i] = 0;
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Insert(s, e)
-
- Returns: void
-
- Purpose: Insert element e into set s.
-
- Plan: Determine the bit in s to which e corresponds, and set
- that bit to 1.
-
- Notes: e may already be in s.
-
- **/
-
- void Insert(s, e)
- set *s; /* in out: the set to receive the element. */
- elementType e; /* in: the element to be inserted. */
- {
- if ( e < s->lower || e > s->upper ) {
- error_occurred = TRUE;
- return;
- }
- s->bits[(e-s->lower)/WORDSIZE] |= 01 << ((e-s->lower)%WORDSIZE);
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Delete(s, e)
-
- Returns: void
-
- Purpose: Delete element e from set s.
-
- Plan: Determine the bit in s to which e corresponds, and set that
- bit to 0.
-
- Notes: e doesn't have to be in s.
-
- **/
-
- void Delete(s, e)
- set *s; /* in out: the set from which to delete. */
- elementType e; /* in: the element to delete. */
- {
- if ( e < s->lower || e > s->upper ) {
- error_occurred = TRUE;
- return;
- }
- s->bits[(e-s->lower)/WORDSIZE] &= ~(01 << ((e-s->lower)%WORDSIZE));
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Empty(s)
-
- Returns: boolean
-
- Purpose: Determine whether a set is empty: return TRUE iff it is.
-
- Plan: Any non-zero bit indicates the set is not empty; test
- for that.
-
- Notes: None.
-
- **/
-
- boolean Empty(s)
- set *s; /* in: the set whose emptiness is to be checked. */
- {
- register int i, Number_Of_Bytes;
- error_occurred = FALSE;
- Number_Of_Bytes = (s->upper - s->lower)/WORDSIZE + 1;
- for ( i = 0; i < Number_Of_Bytes; i++ )
- if ( s->bits[i] )
- return FALSE;
- return TRUE;
- }
-
- /**************************************************************************
-
- Member(s, e)
-
- Returns: boolean
-
- Purpose: Determine if e is a member of s: return TRUE iff it is.
-
- Plan: Check the bit to which e corresponds.
-
- Notes: None.
-
- **/
-
- boolean Member(s, e)
- set *s;
- elementType e;
- {
- if ( error_occurred = (e < s->lower || e > s->upper) )
- return FALSE;
- return (s->bits[(e - s->lower)/WORDSIZE] >> (e - s->lower)%WORDSIZE) & 01;
- }
-
- /* The following macro tests whether two sets have an equivalent domain --
- * i.e., bounds. It is only possible to perform the boolean operations
- * on equivalent sets.
- */
- #define equivalent(s1, s2) \
- ((s1)->lower==(s2)->lower && (s1)->upper==(s2)->upper)
-
- /**************************************************************************
-
- Unite(s1, s2, s3)
-
- Returns: void
-
- Purpose: Return in s3 the union of sets s1 and s2.
-
- Plan: Use the bitwise OR operator to construct the union
- of each set of words in s1 and s2.
-
- Notes: None.
-
- **/
-
- void Unite(s1, s2, s3)
- set *s1, *s2; /* in: the sets to be united. */
- set *s3; /* out: the union of s1 and s2. */
- {
- register int i, Number_Of_Bytes;
-
- if ( ! (equivalent(s1, s2) && equivalent(s2, s3)) ) {
- error_occurred = TRUE;
- return;
- }
-
- Number_Of_Bytes = (s1->upper - s1->lower)/WORDSIZE + 1;
- for ( i = 0 ; i < Number_Of_Bytes; i++ )
- s3->bits[i] = (s1->bits[i] | s2->bits[i]);
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Intersect(s1, s2, s3)
-
- Returns: void
-
- Purpose: Return in s3 the intersection of s1 and s2.
-
- Plan: Use the bitwise AND operator to construct the intersection
- of s1 and s2.
-
- Notes: None.
-
- **/
- void Intersect(s1, s2, s3)
- set *s1, *s2; /* in: the sets to be intersected. */
- set *s3; /* out: the intersection of s1 and s2. */
- {
- register int i, Number_Of_Bytes;
-
- if ( ! (equivalent(s1, s2) && equivalent(s2, s3)) ) {
- error_occurred = TRUE;
- return;
- }
-
- Number_Of_Bytes = (s1->upper - s1->lower)/WORDSIZE + 1;
- for ( i = 0 ; i < Number_Of_Bytes; i++ )
- s3->bits[i] = (s1->bits[i] & s2->bits[i]);
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Subtract(s1, s2, s3)
-
- Returns: void
-
- Purpose: Return in s3 the difference between s1 and s2 (i.e., s1-s2).
-
- Plan: Use the formula (A&~B) on each corresponding pair of
- words in s1 and s2.
-
- Notes: None.
-
- **/
-
- void Subtract(s1, s2, s3)
- set *s1, *s2; /* in: the sets to be subtracted. */
- set *s3; /* out: the difference between s1 and s2. */
- {
- register int i, Number_Of_Bytes;
-
- if ( ! (equivalent(s1, s2) && equivalent(s2, s3)) ) {
- error_occurred = TRUE;
- return;
- }
-
- Number_Of_Bytes = (s1->upper - s1->lower)/WORDSIZE + 1;
- for ( i = 0 ; i < Number_Of_Bytes; i++ )
- s3->bits[i] = s1->bits[i] & ~(s2->bits[i]);
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Copy(source, destination)
-
- Returns: void
-
- Purpose: Create a copy of a set.
-
- Plan: Trivial.
-
- Notes: None.
-
- **/
-
- void Copy(source, destination)
- set *source, /* in: the set to be copied. */
- *destination; /* out: a copy of "source". */
- {
- register int i;
-
- if ( ! equivalent(source, destination) ) {
- error_occurred = TRUE;
- return;
- }
- for ( i = 0; i < MAX_ELEMENTS/WORDSIZE; i++ )
- destination->bits[i] = source->bits[i];
- error_occurred = FALSE;
- }
-
- /**************************************************************************
-
- Iterate(s, f)
-
- Returns: void
-
- Purpose: Perform some application-defined function f on each element
- of set s. The function f() should be of the form:
-
- boolean f(e)
- elementType e;
-
- The iteration will continue as long as more elements
- remain in the set and f() returns TRUE.
-
- Plan:
-
- Notes: There is no guaranteed order in which the elements are
- passed to f().
-
- **/
-
- void Iterate(s, f)
- set *s; /* in: the set to iterate through. */
- boolean (*f)(); /* in: the function to perform on the elements. */
- {
- register int i, j, Number_Of_Bytes;
- Number_Of_Bytes = (s->upper - s->lower)/WORDSIZE + 1;
-
- error_occurred = FALSE;
-
- for ( i = 0; i < Number_Of_Bytes; i++ )
- for ( j = 0; j < WORDSIZE; j++ )
- if ( (s->bits[i] >> j) % 2 )
- if ( ! (*f)(j + i*WORDSIZE + s->lower) )
- return;
- }
-
- /**************************************************************************
-
- Error_Occurred()
-
- Returns: boolean
-
- Purpose: Indicate whether the last operation could not be
- completed due to some error.
-
- Plan: The routine's value is the value of the local variable
- "error_occurred".
-
- Notes: It is the responsibility of each routine to correctly
- set "error_occurred".
-
- **/
-
- boolean Error_Occurred()
- {
- return error_occurred;
- }
-